﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Metadata.Edm;
using System.Linq;
using System.Text;
using EzDesk.Apps.Data.ProjectModule;
using EzDesk.Apps.Interface.ProjectModule;
using EzDesk.Apps.Model.ProjectModule;
using EzDesk.Utility.ServiceStatusInfo;
using EzDesk.Utility.Json;

namespace EzDesk.Apps.ServiceImpl.ProjectModule
{
    public partial class ProjectService : IProjectService
    {
        private string FeedTemplateStr_project_newSelfWorkItemAdded = "project_newSelfWorkItemAdded";
        private string FeedTemplateStr_project_newAssignWorkItemAdded = "project_newAssignWorkItemAdded";
        private string FeedTemplateStr_project_workitemTodo = "project_workitemTodo";

        #region [ private methods ]

        private void sendNewAssignWorkItemAddedFeed(Workitem workItem)
        {
            var actor = _ezApiClient.GetSimpleUserById(workItem.CreatorId);
            var owner = _ezApiClient.GetSimpleUserById(workItem.OwnerId);
            var workitemId = workItem.Id.ToString();
            var titleContent = workItem.Title;
            var feedData = new Dictionary<string, string>()
                {
                    {"ownerName", owner.Name},
                    {"actorName", actor.Name},
                    {"workitemId", workitemId},
                    {"titleContent", titleContent}
                };

            _ezApiClient.SendFeed(
                FeedTemplateStr_project_newAssignWorkItemAdded,
                JsonHelper.ConvertToJson(feedData),
                owner.Id.ToString()
                );
        }


        private void sendNewSelfWorkItemAddedFeed(Workitem workItem)
        {
            var actor = _ezApiClient.GetSimpleUserById(workItem.OwnerId);
            var workitemId = workItem.Id.ToString();
            var titleContent = workItem.Title;
            var feedData = new Dictionary<string, string>()
                               {
                                   {"actorName", actor.Name},
                                   {"workitemId", workitemId},
                                   {"titleContent", titleContent},
                               };

            _ezApiClient.SendFeed(
                FeedTemplateStr_project_newSelfWorkItemAdded,
                JsonHelper.ConvertToJson(feedData),
                "everyone"
                );
        }


        /// <summary>
        /// 将一条Workitem添加到被执行人的TODO列表中
        /// </summary>
        /// <param name="workitem"></param>
        private void sendWorkitemTodoFeed(Workitem workitem)
        {
            var feedData = getFeedDataForWorkitemTodo(workitem);

            var memberstring = workitem.OwnerId.ToString();

            var feedId = _ezApiClient.SendFeed(
                FeedTemplateStr_project_workitemTodo,
                JsonHelper.ConvertToJson(feedData),
                memberstring
                );
            _ezApiClient.SetFeedRecord(workitem.Id, FeedTemplateStr_project_workitemTodo, memberstring, feedId, null);
        }

        /// <summary>
        /// 完成任务时，更新workitem的Todo
        /// </summary>
        private void updateWorkItemTodoFeed(Workitem workitem)
        {
            // 找到这条TODO，如果有的话，更新一下FeedData
            var memberstring = workitem.OwnerId.ToString();
            var feedIdStr = _ezApiClient.GetFeedRecord(workitem.Id, FeedTemplateStr_project_workitemTodo,
                                                    memberstring);
            var newFeedData = getFeedDataForWorkitemTodo(workitem);
            _ezApiClient.UpdateFeedsData(feedIdStr, JsonHelper.ConvertToJson(newFeedData));
            _ezApiClient.SetFeedsIsRead(feedIdStr, memberstring, true);
        }

        private Dictionary<string, string> getFeedDataForWorkitemTodo(Workitem workitem)
        {
            var workitemId = workitem.Id.ToString();
            var titleContent = workitem.Title;
            var creator = _ezApiClient.GetSimpleUserById(workitem.CreatorId);
            var creatorName = creator.Name;

            var descriptionContent = "";
            if (!string.IsNullOrEmpty(workitem.Description))
            {
                descriptionContent = "<ez:br />" + workitem.Description;
            }

            var endTime = "";
            if (workitem.IsFinished)
            {
                endTime = "<ez:br />" + "已经完成";
                //todo: 加入截止日期的提示
                //endTime = "<ez:br />" + workitem.
            }


            var feedData = new Dictionary<string, string>
                               {
                                   {"workitemId", workitemId},
                                   {"titleContent", titleContent},
                                   {"creatorName", creatorName},
                                   {"descriptionContent", descriptionContent},
                                   {"endTime", endTime},
                               };
            return feedData;
        }


        private Workitem getWorkitemById(Guid workitemId)
        {
            var item = EzDeskProjectContainer.Go(
                entity => entity.WorkitemSet.FirstOrDefault(p => p.Id == workitemId));
            if (item == null)
            {
                throw new Exception("没有找到对应的工作任务");
            }
            return item;
        }

        #endregion

        public StatusInfo<Guid> AddWorkitem(Workitem workItem)
        {
            return StatusInfo.Wrap(
                () =>
                {
                    var newWorkitemId = Guid.NewGuid();
                    workItem.Id = newWorkitemId;
                    EzDeskProjectContainer.GoAndSave(
                        entity => entity.WorkitemSet.AddObject(workItem));

                    if (workItem.IsSelfWorkitem())
                        sendNewSelfWorkItemAddedFeed(workItem);
                    else
                        sendNewAssignWorkItemAddedFeed(workItem);

                    sendWorkitemTodoFeed(workItem);
                    return newWorkitemId;
                });
        }

        public StatusInfo<Guid> AddFinishedWorkitem(Workitem workItem)
        {
            return StatusInfo.Wrap(
                () =>
                {
                    var newWorkitemId = Guid.NewGuid();
                    workItem.Id = newWorkitemId;
                    workItem.IsFinished = true;
                    EzDeskProjectContainer.GoAndSave(
                        entity => entity.WorkitemSet.AddObject(workItem));
                    return newWorkitemId;
                });
        }

        public StatusInfo<List<Workitem>> GetWorkitems(
            Guid? ownerId, Guid? creatorId, Guid? projectId,
            bool? isFinished,
            DateTime? startCreateOn, DateTime? endCreateOn,
            DateTime? startFinishOn, DateTime? endFinishOn,
            int? maxCount)
        {
            return StatusInfo.Wrap(
                () =>
                {
                    var workitems = EzDeskProjectContainer.Go(
                        container =>
                        {
                            IQueryable<Workitem> query = container.WorkitemSet;
                            if (ownerId.HasValue)
                            {
                                query = query.Where(p => p.OwnerId == ownerId.Value);
                            }
                            if (creatorId.HasValue)
                            {
                                query = query.Where(p => p.CreatorId == creatorId.Value);
                            }
                            if (projectId.HasValue)
                            {
                                query = query.Where(p => p.Project.Id == projectId.Value);
                            }
                            if (isFinished.HasValue)
                            {
                                query = query.Where(p => p.IsFinished == isFinished.Value);
                            }
                            if (startCreateOn.HasValue)
                            {
                                query = query.Where(p => p.CreateOn >= startCreateOn.Value);
                            }
                            if (endCreateOn.HasValue)
                            {
                                query = query.Where(p => p.CreateOn <= endCreateOn.Value);
                            }
                            if (startFinishOn.HasValue)
                            {
                                query = query.Where(p => p.FinishOn >= startFinishOn.Value);
                            }
                            if (endFinishOn.HasValue)
                            {
                                query = query.Where(p => p.FinishOn <= endFinishOn.Value);
                            }
                            if (maxCount.HasValue)
                            {
                                query = query.Take(maxCount.Value);
                            }
                            return query.ToList();
                        });
                    return workitems;
                });
        }

        public StatusInfo<Workitem> GetWorkitem(Guid workitemId)
        {
            return StatusInfo.Wrap(
                () =>
                {
                    var item = getWorkitemById(workitemId);
                    return item;
                });
        }



        public StatusInfo FinishWorkitem(Guid workitemId, Guid actorId, int estimatePoint)
        {
            return StatusInfo.Wrap(
                () =>
                {
                    var workitem = getWorkitemById(workitemId);
                    if (workitem.OwnerId != actorId)
                    {
                        throw new Exception("只有这个任务的负责人才能完成这个任务");
                    }
                    if (workitem.IsFinished)
                    {
                        throw new Exception("这个任务已经被完成了");
                    }
                    EzDeskProjectContainer.GoAndSave(container =>
                                                         {
                                                             container.WorkitemSet.Attach(workitem);
                                                             workitem.FinishOn = DateTime.Now;
                                                             workitem.IsFinished = true;
                                                             workitem.Points = estimatePoint;
                                                         });
                    updateWorkItemTodoFeed(workitem);
                }
                );
        }

    }
}
